/**
 * 提示文本框
 *
 * @author Fengming Sun <sunfengming@ec3s.com>
 */
(function(){
    var TipText = this.TipText = new Class({
        textbox: null,
        pressTimeout: null,
        ajaxRequest: null,
        ajax: null,
        tipBox: null,
        tipData: {},
        isShow: false,
        tipPos: -1,
        initialize: function(textbox){
            var _this = this;
            if (1 > textbox.length || !textbox.get('ajax')) {
                return false;
            }
            this.textbox = textbox;
            this.textbox.set('autocomplete', 'off');
            this.ajax = this.textbox.get('ajax');
            this.textbox.addEvent('keydown', function(e){
                if (![13, 27, 37, 38, 39, 40].contains(e.code)) {
                    _this.delayFind(_this);
                }
            });
        },
        delayFind: function(obj){
            var _this = obj;
            _this.hideTipBox();
            if (null !== _this.pressTimeout) {
                clearTimeout(_this.pressTimeout);
                if (null !== _this.ajaxRequest) {
                    _this.ajaxRequest.cancel();
                }
            }
            _this.pressTimeout = setTimeout(function(){
                _this.findTips(_this);
            }, 500);
        },
        findTips: function(obj){
            var _this = obj;
            var findText = _this.textbox.value;
            var tips = [];
            if ('' === findText.trim()) {
                return false;
            }
            // cache the tip data
            if (!$defined(_this.tipData[findText])) {
                //ajax post data to search tip data
                _this.ajaxRequest = new Request({
                    url: _this.ajax,
                    method: 'post',
                    onComplete: function(msg){
                        _this.tipData[findText] = msg;
                        _this.showTipBox(findText);
                    }
                }).send('pname=' + findText);
            } else {
                _this.showTipBox(findText);
            }
            
        },
        showTipBox: function(findText){
            if ('[]' === this.tipData[findText]) {
                return false;
            }
            var textboxWidth = this.textbox.getSize().x;
            var textboxHeight = this.textbox.getSize().y;
            var textboxPosition = this.textbox.getPosition();
            if (null === this.tipBox) {
                this.tipBox = new Element('div');
                this.tipBox.setStyles({
                    'border': '1px solid #C9C9C9',
                    'background': '#FFF',
                    'width':  textboxWidth - 2 + 'px',
                    'height': '150px',
                    'overflow-y': 'auto',
                    'overflow-x': 'hidden',
                    'position': 'absolute'
                });
                $$('body')[0].adopt(this.tipBox);
            }
            this.tipBox.setStyles({
                'display': 'block'
            });
            this.tipBox.setPosition({x: textboxPosition.x, y: textboxPosition.y + textboxHeight});
            this.loadTips(this.tipData[findText]);
            this.isShow = true;
            var _this = this;
            $(window).addEvent('keydown', function(e){
                if ([13, 38, 40].contains(e.code)) {
                    e.stop();
                    _this.chooseTip(_this, e.code);
                } else if (27 === e.code) {
                    e.stop();
                    _this.hideTipBox();
                }
            });
        },
        hideTipBox: function(){
            if (null !== this.tipBox) {
                this.tipBox.setStyles({
                    'display': 'none'
                });
                this.unloadTips();
                this.isShow = false;
            }
            $(window).removeEvents('keydown');
        },
        loadTips: function(tips){
            tips = eval(tips);
            var _this = this;
            var ul = new Element('ul');
            tips.each(function(item, index){
                var tmpli = new Element('li').appendText(item);
                tmpli.setStyles({
                    'line-height': '30px',
                    'border-bottom': '1px solid #CFCFCF',
                    'padding': '0 5px'
                });
                ul.adopt(tmpli);
                tmpli.addEvent('mouseover', function(e){
                    ul.getElements('li').each(function(item){
                       _this.blurTip(item);
                    });
                    _this.focusTip(this);
                    _this.tipPos = index;
                    _this.textbox.value = this.get('text');
                });

                tmpli.addEvent('click', function(e){
                    _this.hideTipBox();
                });
            });
            this.tipBox.adopt(ul);
        },
        unloadTips: function(){
            this.tipBox.empty();
            this.tipPos = -1;
        },
        focusAndScroll: function(tip){
            this.focusTip(tip);
            tipScrollTop = tip.getPosition(this.tipBox).y;

            if (tipScrollTop > this.tipBox.getScroll().y + this.tipBox.getSize().y || tipScrollTop < this.tipBox.getScroll().y) {
                this.tipBox.scrollTo(0, tipScrollTop);
            }
        },
        chooseTip: function(obj, code){
            var _this = obj;
            var tipItems = _this.tipBox.getElements('li');
            if (_this.tipPos < tipItems.length - 1 && code === 40) {
                _this.tipPos ++;
                _this.focusAndScroll(tipItems[_this.tipPos]);
                if (1 <= _this.tipPos) {
                    _this.blurTip(tipItems[_this.tipPos - 1]);
                }
                _this.textbox.value = tipItems[_this.tipPos].get('text');
            } else if (_this.tipPos > 0 && code === 38) {
                _this.tipPos --;
                _this.focusAndScroll(tipItems[_this.tipPos]);
                if (_this.tipPos < tipItems.length - 1) {
                    _this.blurTip(tipItems[_this.tipPos + 1]);
                }
                _this.textbox.value = tipItems[_this.tipPos].get('text');
            } else if (code === 13) {
                _this.hideTipBox();
            }
        },
        focusTip: function(tipItem){
            tipItem.setStyles({
                'background': '#435786',
                'color': '#FFF'
            });
        },
        blurTip: function(tipItem){
            tipItem.setStyles({
                'background': '#FFF',
                'color': '#666'
            });
        }
    });
})();